import grails.converters.JSON
import javax.servlet.http.Cookie
import org.springframework.context.MessageSource
import org.springframework.web.servlet.support.RequestContextUtils as RCU;

class GalleryController {

  def beforeInterceptor = [action:this.&auth]
  
  MessageSource messageSource

  static final String YEAR_PARAM = 'year'
  static final String MONTH_PARAM = 'month'
  static final String INDEX_PARAM = 'index'

  private static final MonthMapByLocale = [:]

  // Initializes month map for current locale
  synchronized def initMonthMap(Locale locale) {
    String[] months = messageSource.getMessage('g.months', null, locale).split(",")
    def mmap = [:]
    for(mid in 0..months.size()-1) {
      mmap.put((mid+1).toString(),months[mid])
    }
    MonthMapByLocale[locale.displayName] = mmap
    return mmap
  }

  // Gets month map for current locale, if none exists -- initializes it
  def getMonthMap(request) {
    Locale locale = RCU.getLocale(request)
    def l = MonthMapByLocale[locale.displayName]
    if(l == null) {
      l = initMonthMap(locale)
    }
    return l
  }

  def index = {
    List<Tag> ytags = Tag.getYearTags()
    Tag ytag = getCurrentOrLastTag(ytags, YEAR_PARAM)
    List<Tag> mtags = Tag.getMonthTagsForYear(ytag)
    Tag mtag = getCurrentOrLastTag(mtags, MONTH_PARAM)
    List<Master> masters = Master.getAllMastersWithTags(ytag, mtag)

    String imgPath = grailsApplication.config.imagesPath;
    String thumbsSubdir = VersionType.PredefinedVersions[0].subdir;

    int i = 0
    String href = "http://www.google.com"
    def thumbnails = masters.collect{ m ->
      String src = imgPath + m.relativePath + "/" + thumbsSubdir + "/" + m.fileName
      // Find thumbnail image (if any)
      Version thumb = m.versions.find{ it.versionTypeId == 0 }
      if(thumb == null) {
        return
      }
      // Render a map
      [src:src, width:thumb.imageWidth, height:thumb.imageHeight, href:href, index:(i++)]
    }

    [thumbnails:thumbnails, ytags:ytags, ytag:ytag, mtags:mtags, mtag:mtag, monthMap:getMonthMap(request)]
  }

  def slideshow = {
    Tag mtag = Tag.getByNameAndType(params[MONTH_PARAM], TagType.MONTH)
    Tag ytag = Tag.getByNameAndType(params[YEAR_PARAM], TagType.YEAR)

    int index = 0;
    String indexParam = params[INDEX_PARAM];
    if(indexParam)
    try {
      index = Integer.parseInt(indexParam)
    } catch(Exception ex) {
      // By design
    }

    if(mtag == null || ytag == null) {
      redirect(action:"index")
      return
    }

    JSON json = getJsonForTags(ytag, mtag)
    [json:json, index:index, year:ytag.name, month:mtag.name]
  }

  private JSON getJsonForTags(Tag... tags) {
    List<Master> masters = Master.getAllMastersWithTags(tags)

    def json = masters.collect { m -> ['p':m.relativePath, 'n':m.fileName, 'c':m.comment,
      'v':m.versions.collect {
          v -> ['t':v.versionTypeId, 'h':v.imageHeight, 'w':v.imageWidth]
        }
      ]
    } as JSON
  }

  //**
  // Gets the currently selected tag based on the parameter in the cookie
  // or on the query string
  //*
  private Tag getCurrentOrLastTag(List<Tag> tags, String paramName) {
    if(tags.empty) {
      return null
    }

    Tag t = null
    String tagName = params[paramName]
    t = findTagWithName(tags, tagName)
    
    if(t == null) { // Invalid param, try to get the cookie
      tagName = request.cookies.find{it.name==paramName}?.value
      t = findTagWithName(tags, tagName)
    }
    
    t = t ?: tags.last()

    if(t != null) {
      Cookie c = new Cookie(paramName, tagName)
      c.maxAge = 60*60*24*365
      response.addCookie(c)
    }

    return t
  }

  private Tag findTagWithName(List<Tag> tags, String name) {
    return (name == null) ? null : tags.find{x->x.name == name}
  }

  private auth() {
    if(!Constants.predefinedRoles.contains(session?.role)){
      flash.message = "Please log in first."
      redirect(controller:"login", action:"index")
      return false
    }
  }
}
